package fr.jade.fraclite.orb;

import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import fr.jade.fraclite.api.ComponentInterface;
import fr.jade.fraclite.orb.api.Binder;
import fr.jade.fraclite.orb.api.Name;
import fr.jade.fraclite.orb.api.NamingException;
import fr.jade.fraclite.orb.api.RemoteReference;

/**
 * 
 * @author <a href="mailto:florent.metral@inrialpes.fr">Florent Metral
 *
 */
public class MulticastStubFactory implements StubFactory {
	
	private ClassLoader cl = null;
	Skeleton s = null;
  ExecutorService es;
  double stubId = 0;
  
	public MulticastStubFactory(ClassLoader cl){
	  this.cl = cl;
	  es = Executors.newCachedThreadPool();
	  stubId = Math.random();
	}

  public Object newStub(Binder binder, Name name) throws NamingException{
    MulticastStub stub = new MulticastStub(name, String.valueOf(stubId++));
    try {
      String signature = name.getSignature();
      Class<?> itf = cl.loadClass(signature);
      Class<?>[] itfs = new Class[]{itf, ComponentInterface.class, RemoteReference.class};
      return Proxy.newProxyInstance(cl, itfs, stub);
    } catch (ClassNotFoundException e) {
      throw new NamingException("Cannot create stub "+e.toString() );
    }
  }
  
  public Object newSkeleton(Map<String,?> hints, Object target, Binder naming) throws NamingException{
    //if(s == null){
      s = new MulticastSkeleton(naming);
      es.execute(s);
    //}
    s.registerTarget(target);
    return s;
  }

  
  
}
